#ifndef MOSES_TYPEVISITOR_H
#define MOSES_TYPEVISITOR_H

#include <stack>
#include <ostream>
#include <string>
#include "Ast.h"

namespace moses
{
	class TypeVisitor : public Visitor
	{
	public:
		TypeVisitor(std::ostream &err);
		
		virtual void Accept(BinaryExpr *pItem);
		virtual void Accept(Call *pItem);
		virtual void Accept(Function *pItem);		
		virtual void Accept(FunctionRow *pItem);
		
		virtual void Accept(Identifier *pItem);
		virtual void Accept(Literal *pItem);
		virtual void Accept(Module *pItem);
		virtual void Accept(Pattern *pItem);
		
		virtual void Accept(Type *pItem);
		virtual void Accept(UnaryExpr *pItem);
			
		unsigned int NumErrors();
		
	private:
		void PushType(Type t);		
		Type PopType();		
		bool StackEmpty();	
		
		std::ostream& Report(Item *pItem);		
		Module* GetModule();	
		
	private:		
		Module *m_pModule;
		
		std::stack<Type> m_stack;
		std::ostream &m_err;
		
		unsigned int m_errors;
	};
}

#endif